#include "thread.hpp"
#include "mutex.hpp"

int ticket = 10000;
// 我来对其进行加锁,先定义一个互斥量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;


//不推荐一下这种写法，加锁解锁应该要包含一个完整的作用域
// void *handler(void *arvg)
// {
//     // 现在我来模拟一下抢票，有10000张票

//     // 这里就是传说中的“临界区”, while循环要判断ticket所以从while这里开始这些共享的资源就必须要是临界资源了
//     pthread_mutex_lock(&mutex);
//     while( ticket > 0)
//     {
      
//        // pthread_mutex_lock(&mutex);
//         usleep(1034);  // 直接休息一毫秒，看现象
//         std::cout << (char *)arvg << "购票成功 : " << ticket << std::endl;
//         ticket--;
//         pthread_mutex_unlock(&mutex);

//         // 这里为了模拟抢完了票后的提示动作，也可以把刚刚解锁的线程换下，防止该线程一直霸占锁
//         //usleep(1024);
//     }
//     //pthread_mutex_unlock(&mutex);
// }

void *handler(void *arvg)
{
  
    
    //减小临界区域
    while(true)
    {
        //pthread_mutex_lock(&mutex);

        // 这种在线程独立栈上创建互斥量的逆天代码以后不要有了
        // pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
        mutexs textMutex(&mutex);
        textMutex.lock();
        {
        if(ticket > 0)
        {
            usleep(1024);
            std::cout << static_cast<const char*>(arvg) <<"正在购票 :" << ticket << std::endl; 
            ticket--;
            //pthread_mutex_unlock(&mutex);
            textMutex.unlock();
        }
        else
        {
            std::cout << "购票失败所有车票已经出售" << std::endl;
            //pthread_mutex_unlock(&mutex);
            textMutex.unlock();
            break;
        }
        }
        // 若购票成功返回break一个线程不要长久的霸占cpu,我们模拟购票后后续的信息，切换线程
        usleep(1024);
    } 
}



int main()
{
    //pthread_mutex_init(&mutex,nullptr);
    // 创建线程出来
    std::unique_ptr<Threads> thread1(new Threads("user1", 1, handler,(void*)"user1"));
    std::unique_ptr<Threads> thread2(new Threads( "user2", 2,handler,(void*)"user2"));
    std::unique_ptr<Threads> thread3(new Threads( "user3", 3,handler,(void*)"user3"));
    std::unique_ptr<Threads> thread4(new Threads( "user4", 4,handler,(void*)"user4"));

  

    thread1->join();
    thread2->join();
    thread3->join();
    thread4->join();

    //pthread_mutex_destroy(&mutex);
    return 0;
}